package com.heima.datastructure.blockingqueue;

/**
 * <h3>阻塞队列</h3>
 * <h3>目前队列存在的问题</h3>
 * <ul>
 *     <li>很多场景要求分离生产者、消费者两个角色，他们得有不同的线程来担当，而之前的实现没有考虑线程安全问题</li>
 *     <li>队列为空，那么在之前的poll实现就会返回null，如果硬要拿到一个元素呢，就只能不断地循环尝试</li>
 *     <li>队列为满，那么在之前的offer实现就会返回false，如果硬要添加一个元素呢，就只能不断地循环尝试</li>
 * </ul>
 * <h3>解决方案</h3>
 * <ul>
 *     <li>用锁保证线程安全</li>
 *     <li>用条件变量让poll或offer线程进入等待状态，而不是不断地循环尝试，让cpu空转</li>
 * </ul>
 * @author 勾新杰
 * @version 1.0
 * @date 2024/9/4 15:13
 */
public interface BlockingQueue<E> {
    /**
     * 阻塞队列入队
     * @param value 入队元素
     * @throws InterruptedException 中断异常
     */
    void offer(E value) throws InterruptedException; // 这个异常通常被抛出到那些正在等待、睡眠或永久阻塞的线程上，以响应线程的中断请求。

    /**
     * 阻塞队列入队
     * @param value 入队元素
     * @param timeout 当前线程阻塞后等待时间上限，限制单位是毫秒
     * @return 当前线程阻塞等待总时间超过timeout或者说timeout毫秒过后队列还是满返回false，其余肯定入队成功，返回true
     * @throws InterruptedException 中断异常
     */
    boolean offer(E value, long timeout) throws InterruptedException;

    /**
     * 出队
     * @return 出队元素的值
     * @throws InterruptedException 中断异常
     */
    E poll() throws InterruptedException;

    /**
     * 出队
     * @param timeout 时间上限
     * @return 被阻塞timeout时间后或者说timeout毫秒时间后如果队列还是空，就返回null，否则返回出队元素
     * @throws InterruptedException 中断异常
     */
    E poll(long timeout) throws InterruptedException;
}
